#ifndef MAPDATA_H
#define MAPDATA_H

#include <vector>
#include <string>
#include <sstream>
#include "Image.h"
#include "PenjinTypes.h"
#include "CollisionObject.h"
#ifdef _DEBUG
    #include "Pixel.h"
#endif


//----------------------------
// by foxblock for Wandor - Sep 01 2009
// This class loads and organizes all the level data (collision, tilemap, maybe even units in the future)
//----------------------------

// Class structs
enum LAYERS
{
    FG,
    BG,
    MID,
    PROP
};
enum PROPERTIES
{
    COLLISION=0,
    BREAKABLE=1,
    PLAYER_REACTION=2,
    PUSH=3,
    GAME=4
};

class MapData
{
public:
    MapData();
    ~MapData();

    // Assign the data
    void assign(const wstring &FGLayer, const wstring &BGLayer, const wstring &PropLayer, CRstring FilePath, CRint transColour, CRint width, CRint height);
    void assign(const wstring &FGLayer, const wstring &MLayer, const wstring &BGLayer, const wstring &PropLayer, CRstring FilePath, CRint transColour, CRint width,CRint height);

    Vector2df getSize() const;
    int getTileSize() const;                                                              // Get the tile size (in pixels)

    int getTileData(CRuint x, CRuint y, const LAYERS layer) const;                  // Get the integer of the graphics tile used at a specific position
    void setTileData(CRuint x, CRuint y, const LAYERS layer, CRint value);
    void setTileData(const Vector2df tile, const LAYERS layer, CRint value) {setTileData(tile.x,tile.y,layer,value);};
    int getCollisionData(CRuint x, CRuint y) const;                                 // Just a wrapper function for getPropertyData(x,y,COLLISION)
    int getCollisionData(const Vector2df tile) const {return getCollisionData(tile.x,tile.y);}
    int getPropertyData(CRuint x, CRuint y, const PROPERTIES prop) const;           // Get the specified property of a tile
    int getPropertyData(const Vector2df tile, const PROPERTIES prop) const {return getPropertyData(tile.x,tile.y,prop);}
    void setPropertyData(CRuint x, CRuint y, const PROPERTIES prop, CRint value);
    void setPropertyData(const Vector2df tile, const PROPERTIES prop, CRint value) {setPropertyData(tile.x,tile.y,prop,value);}

    void slideTileData(CRuint x, CRuint y, CRuint width, CRuint height, CRint xoffset, CRint yoffset); // scroll or slide a portion of the layer

    void render(const LAYERS Layer, const Vector2df Offset);         // Render the visible map at an offset

    // Utility functions
    void removeCameraTiles(const CollisionObject* const obj, const Vector2df& pos, const Vector2df& tilesX, const Vector2df& tilesY); // removes touched camera tiles
    Vector2df breakTiles(const CollisionObject* const obj, CRint state, CRbool dirX, CRbool dirY); // destroys hit blocks, which are destroyable and returns new correction vector
private:
    string baseConvert(CRint number) const;                                           // Converts Base10 into Base8
    void slideTileDataX(CRuint x, CRuint y, CRuint width, CRuint height, CRint xoffset); // scroll or slide a portion of the layer
    void slideTileDataY(CRuint x, CRuint y, CRuint width, CRuint height, CRint yoffset); // scroll or slide a portion of the layer

    bool m_isLoaded;
    Image m_TileMap;
    Image propImages;
    float sizeOffset;
    vector< vector<string> > m_PropLayer;
    vector< vector<int> > m_FGLayer;
    vector< vector<int> > m_MLayer;
    vector< vector<int> > m_BGLayer;
    #ifdef _DEBUG
    Pixel pix;
    #endif
};

#endif // MAPDATA_H

